﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;                       //STANDARD for WPF App
using System.Windows.Controls;              //STANDARD for WPF App

//STANDARD for WPF App
//STANDARD for WPF App
using System.Windows.Ink;                   //For : InkCanvas
using System.Windows.Input;                 //For : ExecutedRoutedEventArgs

//For : DrawingAttributes
//For : XamlWriter
using System.Windows.Media;                 //For : DrawingGroup

//STANDARD for WPF App
//For : BitmapImage etc etc
//STANDARD for WPF App
using System.Windows.Shapes;                //For : Geometric shapes like Line
using BitsOfStuff.GUI;
using BitsOfStuff.MyActions;
using BitsOfStuff.Support;
using Microsoft.Win32;

//For : OpenFileDialog / SaveFileDialog

namespace BitsOfStuff
{
    /// <summary>
    /// Main graphic windows of aplication
    /// </summary>
    public partial class InkPadWindow
    {
        // Make the pad 4 inches by 5 inches.
        /// <summary>
        /// read only double for stable width
        /// </summary>
        public static readonly double widthCanvas = 8 * 96;
        /// <summary>
        /// read only double for stable height
        /// </summary>
        public static readonly double heightCanvas = 5 * 96;

        /// <summary>
        /// Referenc for recognizer class
        /// </summary>
        public static MyCharRecognizer CharRecognizer;
        /*
                List<List<int>> _listOfSequence = new List<List<int>>();
        */
        private readonly List<int> _lastChar = new List<int>();
        private readonly MyShapeRecognize _myShapeRecognize;
        private readonly NewCharWindow _newCharWindow;

        /// <summary>
        /// Constructor of class whithout paramates
        /// </summary>
        public InkPadWindow()
        {
            _myShapeRecognize = new MyShapeRecognize(
                new BasicCurvedAnalysis(),
                inkCanv
                );

            this.InitializeComponent();

            if (inkCanv.IsGestureRecognizerAvailable)
            {
                inkCanv.EditingMode = InkCanvasEditingMode.InkAndGesture;
                inkCanv.Gesture += new InkCanvasGestureEventHandler(inkCanv_Gesture);
                inkCanv.SetEnabledGestures(new ApplicationGesture[] { ApplicationGesture.Circle });
            }

            //MyParameters.debugBox = this.sequenceLog;
            MyParameters.debugText = this.lastSequence;
            MyParameters.timerSignal = this.timerSignl;
            MyParameters.inkCanvas = this.inkCanv;
            FootstepRecognition.reInitial();
            _newCharWindow = new NewCharWindow(_myShapeRecognize, this);

            inkCanv.AddHandler(InkCanvas.MouseDownEvent,
                               new MouseButtonEventHandler(inkCanvas_MouseDown), true);

            //this.radInk.IsChecked = true;
            this.fishButtons.magnification = 3.5;
            penSize_Click(null, null);

            // Draw blue horizontal lines 1/4 inch apart.
            double y = 24;

            while (y < heightCanvas)
            {
                Line Line = new Line();
                Line.X1 = 0;
                Line.Y1 = y;
                Line.X2 = widthCanvas;
                Line.Y2 = y;
                Line.Stroke = Brushes.LightBlue;
                this.inkCanv.Children.Add(Line);

                y += 24;
            }
        }

        private void inkCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            _myShapeRecognize.setDefinitive();
            //TODO Mouse down evet handler
            if (_myShapeRecognize.isInDecisionState())
            {
                MyPoint contactPoint = new MyPoint();
                contactPoint.setX(e.MouseDevice.GetPosition(inkCanv).X);
                contactPoint.setY(e.MouseDevice.GetPosition(inkCanv).Y);
                _myShapeRecognize.tryChangeDecisionState(contactPoint);
            }
            else
            {
                if (_myShapeRecognize.getLastActionMade() && !_myShapeRecognize.getRecorMode())
                {
                    this.inkCanv.Strokes.Clear();
                    this.inkCanv.Children.Clear();
                    SupportDrawnFunctions.reDrawnInkCanvas(inkCanv);
                    _myShapeRecognize.clear();
                }
            }
        }

        // New command: just clear all the strokes.
        private void btnNew_Click(object sender, RoutedEventArgs args)
        {
            clearStroke();
        }

        /// <summary>
        /// Function that stops all analyzion and clean drawing area
        /// </summary>
        public void clearStroke()
        {
            this.inkCanv.Strokes.Clear();
            this.inkCanv.Children.Clear();
            SupportDrawnFunctions.reDrawnInkCanvas(inkCanv);
            _myShapeRecognize.clear();
        }

        // Load new profile
        private void btnOpen_Click(object sender, RoutedEventArgs args)
        {
            loadProfile();
        }

        private void loadProfile()
        {
            var dlg = new OpenFileDialog();
            dlg.CheckFileExists = false;
            dlg.Filter = "Char recognize user profile (*.crup)|*.crup|" +
                         "All files (*.*)|*.*";

            if ((bool)dlg.ShowDialog(this))
            {
                this.inkCanv.Strokes.Clear();

                try
                {
                    if (!File.Exists(dlg.FileName))
                    {
                        //Create new user profile
                        MessageBox.Show("User profile created", Title);
                        _myShapeRecognize.creatUserProfile(dlg.FileName);
                    }
                    else
                    {
                        _myShapeRecognize.loadUserProfile(dlg.FileName);
                    }
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, Title);
                }
            }
        }

        private void saveProfile()
        {
        }

        // File Save : display SaveFileDialog.
        private void btnSave_Click(object sender, RoutedEventArgs args)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Ink Serialized Format (*.crup)|*.crup|" + "All files (*.*)|*.*"; ;
            dlg.FileName = _myShapeRecognize.getUserProfileFilePath();
            if ((bool)dlg.ShowDialog(this))
            {
                try
                {
                    _myShapeRecognize.saveUserProfile(dlg.FileName);
                    MessageBox.Show("Profile saved :)", Title);
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message, Title);
                }
            }
        }

        // Cut command: cut all selected strokes
        private void btnCut_Click(object sender, RoutedEventArgs args)
        {
            CharRecognizer.findSequenceVectors(_lastChar);
        }

        // Copy command: copy all selected strokes
        private void btnCopy_Click(object sender, RoutedEventArgs args)
        {
            if (this.inkCanv.GetSelectedStrokes().Count > 0)
                this.inkCanv.CopySelection();
        }

        // SAVE CHAR TO STROKE
        private void btnPaste_Click(object sender, RoutedEventArgs args)
        {
            _myShapeRecognize.switchRecordMode();
            if (_myShapeRecognize.getRecorMode())
            {
                btnPaste.Foreground = new SolidColorBrush(Colors.Red);
            }
            else
            {
                btnPaste.Foreground = new SolidColorBrush(Colors.White);
                _newCharWindow.Show();
            }
        }

        // Corect stroke!
        private void btnDelete_Click(object sender, RoutedEventArgs args)
        {
            _myShapeRecognize.switchCorectionMode();
            if (_myShapeRecognize.getCorectionMode())
            {
                btnDelete.Foreground = new SolidColorBrush(Colors.Green);
            }
            else
            {
                btnDelete.Foreground = new SolidColorBrush(Colors.White);
                _newCharWindow.Show();
            }
        }

        // Delete one char
        private void btnSelectAll_Click(object sender, RoutedEventArgs args)
        {
            _myShapeRecognize.deleteMode = true;
            _newCharWindow.Show();
        }

        private void rad_Click(object sender, RoutedEventArgs e)
        {
            RadioButton rad = sender as RadioButton;
            this.inkCanv.EditingMode = (InkCanvasEditingMode)rad.Tag;
        }

        private void txtExit_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.popAbout.IsOpen = false;
            this.popExit.IsOpen = true;
        }

        private void txtAbout_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.popExit.IsOpen = false;
            this.popAbout.IsOpen = true;
        }

        private void txtPopClose_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.popAbout.IsOpen = false;
        }

        private void txtPopExitClose_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            this.popExit.IsOpen = false;
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            App.Current.Shutdown();
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.popExit.IsOpen = false;
        }

        private void penSize_Click(object sender, RoutedEventArgs e)
        {
            //RadioButton rad = sender as RadioButton;
            DrawingAttributes inkDA = new DrawingAttributes();
            inkDA.Width = 6;
            inkDA.Height = 6;
            inkDA.Color = this.inkCanv.DefaultDrawingAttributes.Color;
            inkDA.IsHighlighter = false;
            this.inkCanv.DefaultDrawingAttributes = inkDA;
            //this.expB.IsExpanded = false;
        }

        private void btnStylusSettings_Click(object sender, RoutedEventArgs e)
        {
            StylusSettings dlg = new StylusSettings();
            VirtualKeyboard keyboard = new VirtualKeyboard();

            dlg.Owner = this;
            dlg.drawingAttributes = this.inkCanv.DefaultDrawingAttributes;
            if ((bool)dlg.ShowDialog().GetValueOrDefault())
            {
                this.inkCanv.DefaultDrawingAttributes = dlg.drawingAttributes;
            }
        }

        private void btnFormat_Click(object sender, RoutedEventArgs e)
        {
        }

        private void inkCanv_StylusUp(object sender, StylusEventArgs e)
        {
            debugFuncion();
        }

        private void inkCanv_StylusButtonUp(object sender, StylusButtonEventArgs e)
        {
            this.inkCanv.Strokes.Clear();
            this.inkCanv.Children.Clear();
            double y = 24;

            while (y < heightCanvas)
            {
                Line Line = new Line();
                Line.X1 = 0;
                Line.Y1 = y;
                Line.X2 = widthCanvas;
                Line.Y2 = y;
                Line.Stroke = Brushes.LightBlue;
                this.inkCanv.Children.Add(Line);

                y += 24;
            }
        }

        private void debugFuncion()
        { // Try getting the DrawingAttributes of the first selected stroke.
            StrokeCollection strokes1 = this.inkCanv.Strokes.Clone();
            StrokeCollection strokes2 = this.inkCanv.Strokes.Clone();
            _myShapeRecognize.analyze(strokes1);
            //grafityRecognize.analyze(strokes);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            loadProfile();
            _myShapeRecognize.assignInkCanvas(inkCanv);
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
        }

        private void inkCanv_StrokeCollected(object sender, InkCanvasStrokeCollectedEventArgs e)
        {
            debugFuncion();
        }

        private void inkCanv_StylusDown(object sender, StylusDownEventArgs e)
        {
            //if (myShapeRecognize.getLastActionMade())
            //   SupportDrawnFunctions.reDrawnInkCanvas(inkCanv);
        }

        private void Window_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
        }

        private void inkCanv_Gesture(object sender, InkCanvasGestureEventArgs e)
        {
            ReadOnlyCollection<GestureRecognitionResult> gestureResults =
       e.GetGestureRecognitionResults();

            // Check the first recognition result for a gesture.
            if (gestureResults[0].RecognitionConfidence ==
                RecognitionConfidence.Strong || gestureResults[1].RecognitionConfidence == RecognitionConfidence.Intermediate)
            {
                if (gestureResults[0].ApplicationGesture == ApplicationGesture.Circle)
                {
                    _myShapeRecognize.forceAddAction(new MyShowAction('O', null));
                }
                if (gestureResults.Count >= 2 && gestureResults[1].ApplicationGesture == ApplicationGesture.Circle)
                {
                    _myShapeRecognize.forceAddActionNoConfifance();
                }
            }
        }

        private void LayoutRoot_PreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
        }

        private void btnProfilNew_Click(object sender, RoutedEventArgs e)
        {
        }
    }
}